/**
 * Copyright 2018-2020 stylefeng & fengshuonan (https://gitee.com/stylefeng)
 * <p>
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * <p>
 * http://www.apache.org/licenses/LICENSE-2.0
 * <p>
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package cn.stylefeng.guns.sys.modular.api.controller;

import cn.stylefeng.guns.base.shiro.ShiroUser;
import cn.stylefeng.guns.sys.core.shiro.ShiroKit;
import cn.stylefeng.guns.sys.core.util.JwtTokenUtil;
import cn.stylefeng.guns.sys.core.util.common.ResponseMsg;
import cn.stylefeng.guns.sys.core.util.common.SysErrorCode;
import cn.stylefeng.guns.sys.core.util.common.SystemConstant;
import cn.stylefeng.guns.sys.modular.system.entity.Role;
import cn.stylefeng.guns.sys.modular.system.entity.User;
import cn.stylefeng.guns.sys.modular.system.mapper.RoleMapper;
import cn.stylefeng.guns.sys.modular.system.mapper.UserMapper;
import cn.stylefeng.guns.sys.modular.system.service.DeptService;
import cn.stylefeng.guns.sys.modular.system.service.WxService;
import cn.stylefeng.roses.core.base.controller.BaseController;
import cn.stylefeng.roses.core.reqres.response.ErrorResponseData;
import cn.stylefeng.roses.core.reqres.response.ResponseData;
import cn.stylefeng.roses.core.util.ToolUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.lly835.bestpay.model.PayResponse;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.crypto.hash.Md5Hash;
import org.apache.shiro.util.ByteSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;

import java.util.HashMap;
import java.util.Map;
import java.util.Random;

/**
 * 接口控制器提供
 *
 * @author stylefeng
 * @Date 2018/7/20 23:39
 */
@RestController
@RequestMapping("/api")
public class WxController extends BaseController {

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private WxService wxService;

    @Autowired
    private  RedisTemplate<String,String> redisTemplate;

    @Autowired
    private  RoleMapper roleMapper;
    @Autowired
    private  DeptService deptService;
    /**
     * api登录接口，通过账号密码获取token
     */
    @RequestMapping("/auth")
    public ResponseData auth(@RequestParam("username") String username,
                       @RequestParam("password") String password) {

        //封装请求账号密码为shiro可验证的token
        UsernamePasswordToken usernamePasswordToken = new UsernamePasswordToken(username, password.toCharArray());

        //获取数据库中的账号密码，准备比对
        User user = userMapper.getByAccount(username,null);

        String credentials = user.getPassword();
        String salt = user.getSalt();
        ByteSource credentialsSalt = new Md5Hash(salt);
        SimpleAuthenticationInfo simpleAuthenticationInfo = new SimpleAuthenticationInfo(
                new ShiroUser(), credentials, credentialsSalt, "");

        //校验用户账号密码
        HashedCredentialsMatcher md5CredentialsMatcher = new HashedCredentialsMatcher();
        md5CredentialsMatcher.setHashAlgorithmName(ShiroKit.hashAlgorithmName);
        md5CredentialsMatcher.setHashIterations(ShiroKit.hashIterations);
        boolean passwordTrueFlag = md5CredentialsMatcher.doCredentialsMatch(
                usernamePasswordToken, simpleAuthenticationInfo);

        if (passwordTrueFlag) {
            HashMap<String, Object> result = new HashMap<>();
           /* result.put("token", "Bearer " + JwtTokenUtil.generateToken(String.valueOf(user.getUserId())));*/
            result.put("user",user);
            Integer type = null;
            if (deptService.getById(user.getDeptId()).getSimpleName().contains("经销商部门")){
                  type = 1 ;
            }else  if (deptService.getById(user.getDeptId()).getSimpleName().contains("门店部门")){
                 type = 2 ;
            }else  if (deptService.getById(user.getDeptId()).getSimpleName().contains("消费者部门")){
                 type = 3 ;
            }else if (deptService.getById(user.getDeptId()).getSimpleName().contains("温州经销商")){
                 type = 4;
            }else {
                type = 5;
            }
            result.put("type",type);
            return ResponseData.success(200,"登录成功",result);
        } else {
            return new ErrorResponseData(500, "账号密码错误！");
        }
    }

    /**
     * 需要 微信支付订单
     * 微信支付发起
     * @param orderId
     * @param returnUrl
     * @return
     */
    @RequestMapping("/create")
    public ModelAndView create(@RequestParam("orderId")String orderId,
                               @RequestParam("returnUrl")String returnUrl,
                               HashMap<String, Object> map){

        //根据订单id查询订单,数据库查询
        /*OrderDTO orderDTO = orderService.findOne(orderId);
        if(orderDTO == null){//订单不存在抛出错误
            throw new SellException(ResultEnum.ORDER_NOT_EXIST);
        }*/

        //微信支付
        //PayResponse payResponse = wxService.create(orderDTO);

        //携带参数传入网页发起支付的前端模板
        map.put("orderId", orderId);
        //map.put("payResponse", payResponse);

        return new ModelAndView("pay/create",map);
    }


    /**
     * 微信异步通知
     * @param notifyData
     */
    @PostMapping("/notify")
    public ResponseData notify(@RequestBody String notifyData) {

        PayResponse payResponse = wxService.notify(notifyData);

        //返回给微信处理结果
        return  ResponseData.success(200,"支付成功",payResponse);
    }

    /**
     * 消费者登录接口
     * @param map
     * @return
     */
    @RequestMapping(value = "/login",method = RequestMethod.POST)
    @ResponseBody
    public ResponseEntity<?> login(@RequestBody Map<String,String> map){

        String phone = map.get("phone");
        String code = map.get("code");
        String password = map.get("password");

        //两种登录方式 1，通过手机验证码登录 2.通过手机号和密码登录
        //1.1判断手机号是否为空
        ResponseMsg msg = new ResponseMsg();
        User user = userMapper.selectOne(new QueryWrapper<User>()
                .eq("phone",phone));
        if (ToolUtil.isEmpty(user)){
            msg.setResponseError(SysErrorCode.PHONE_NOTEXITS);
        }else {
            if (ToolUtil.isNotEmpty(code)){
                //1.2如果消费者用手机验证方式登录
                String codeSelect = redisTemplate.opsForValue().get(phone);
                if (code.equals(codeSelect)){
                    msg.setResponseSuccess("登录成功",user);
                }else {
                    msg.setResponseError(SysErrorCode.SMSCODE_ERROR);
                }
            }else if (ToolUtil.isNotEmpty(password)){
                //1.3如果消费者使用手机+密码的形式登录
                String salt = user.getSalt();
                String passwordDes = ShiroKit.md5(password,salt);
                if (user.getPassword().equals(passwordDes)){
                    msg.setResponseSuccess("登录成功",user);
                }else {
                    msg.setResponseError(SysErrorCode.LOGGER_ERROR);
                }
            }
        }
        return  new ResponseEntity<>(msg, HttpStatus.OK);
    }

    /**
     * 重新设置密码
     *
     * @author ZhangJun
     * @Date 2019/6/22
     */
    @RequestMapping(value = "/changePwd",method = RequestMethod.POST)
    public ResponseData changePwd(@RequestParam("newPwd") String newPwd,@RequestParam("phone") String phone){
        String salt=ShiroKit.getRandomSalt(4);
        newPwd=ShiroKit.md5(newPwd,salt);
        userMapper.changePwd(phone,newPwd);
        System.out.printf("√√√√√√");
        System.out.printf("newPwd="+newPwd+",phone+"+phone);
        return  ResponseData.success();
    }


    /**
     * 手机短信发送,验证码存储到缓存中,测试用，用完删除
     * @return
     */
    @RequestMapping("/sendMessage")
    public ResponseData senPhoneMessage(String phone){

        String random = ShiroKit.getRandomSalt(4);
        //随机生成四位验证码放在缓存
        redisTemplate.opsForValue().set(phone,random);
        return ResponseData.success(200,"存到缓存成功",random);

    }

    /*------------------手机发送短信暂时不能用，随机生成4位验证码字符串放到缓存里面(售后注册接口)-------------------------------------------------------------------------*/
    @RequestMapping(value = "/register",method = RequestMethod.POST)
    public  ResponseData register(String phoneCode,String phone,String password){

        //取出缓存和用户输入的验证码 进行对比
        String code = (String) redisTemplate.opsForValue().get("ceshi1");
        if (ToolUtil.isNotEmpty(code)){
            if (phoneCode.equals(code.toString())){

                //将用户数据出入到数据库中
                User user = new User();
                //设置默认头像
                user.setAvatar(SystemConstant.TENCENT_URL.concat("20190624160803_6705.jfif"));
                user.setAccount(phone);
                //密码加盐加密存到数据库
                //1.获取随机盐值
                String salt = ShiroKit.getRandomSalt(4);
                user.setSalt(salt);
                //2.密码加密
                String passwordDes = ShiroKit.md5(password,salt);
                user.setPassword(passwordDes);
                //3.默认昵称
                user.setName("hybn".concat(new Random(5).toString()));
                user.setPhone(phone);
                //默认设置成消费者
                Role role = roleMapper.selectOne(new QueryWrapper<Role>()
                        .like("name","消费者"));
                if (ToolUtil.isNotEmpty(role)){
                    user.setRoleId(role.getRoleId().toString());
                }
                //插入到数据库
                userMapper.insert(user);
                return  ResponseData.success(200,"注册成功",user);
            }else {
                return  ResponseData.error(201,"验证码不一致");
            }
        }else {
            return  ResponseData.error(202,"缓存失败");
        }

    }

}

